/**
    Copyright (c) 2010 ATTi 
    All rights reserved.
    Author: Michael Shu
    Date: 10/7/2010
*/
@isTest

private class AASFieldUpdateHelperClassTester {
    private static String AAS_Operations_Team = 'AAS Operations Team';
    private static String Advanced_Ad_Solutions = 'Advanced Ad Solutions';
    private static String Advanced_Ad_Solutions_AAS_Visitor = 'Advanced Ad Solutions (AAS Visitor)';
    private static String Advanced_Ad_Solutions_Client_Services = 'Advanced Ad Solutions (Client Services)';
    private static String Advanced_Ad_Solutions_Delegated_Admin = 'Advanced Ad Solutions (Delegated Admin)';
    private static String Advanced_Ad_Solutions_BNI_CMR = 'Advanced Ad Solutions-BNI CMR';
    private static Set<String> AASProfileList = new Set<String>{AAS_Operations_Team
                                                              , Advanced_Ad_Solutions
                                                              , Advanced_Ad_Solutions_AAS_Visitor
                                                              , Advanced_Ad_Solutions_Client_Services
                                                              , Advanced_Ad_Solutions_Delegated_Admin
                                                              , Advanced_Ad_Solutions_BNI_CMR};
    private static Set<String> AASUserRoleList = new Set<String>
    {  
       'Regional VP Central', 
       'Pre-Sales Director', 
       'Manager of Ad Operations', 
       'ADSAM', 
       'Central AE',
       'RVP Central/West Integrated Sales',
       'RVP Online/Mobile Sales',
       'VP Product & Operations',
       'RVP Audience Development',
       'BNI-CMR'
    };
    private static Map<String, User> users = new Map<String, User>();

    private static void initFirstFlags(){
        AASFieldUpdateHelperClass.hasNOTUpdateOpportnityWithAccount = true; 
    }   
    
    public static void addUsers(){
        List<Profile> profiles = [select ID, Name from Profile where Name IN: AASProfileList];
        UserRole userrole = [select ID, Name from UserRole where Name IN: AASUserRoleList limit 1];
        List<User> user_insert = new List<User>();
        Integer i = 0;
        for(Profile p : profiles){
            User u_new = new User();
            u_new.UserName = 'xyz_1234567890@atti-temp.com' + i;
            u_new.LastName = 'Michael Shu Test Email' + i;
            u_new.Email = 'xyz_1234567890@atti.com';
            u_new.Alias = 'abcde' + i;
            u_new.CommunityNickname = 'xyaz_1234556' + i;
            u_new.TimeZoneSidKey = 'America/Los_Angeles';
            u_new.LocaleSidKey = 'en_US';
            u_new.EmailEncodingKey = 'UTF-8';
            u_new.ProfileId = p.Id;
            u_new.UserRoleId = userrole.Id;
            u_new.LanguageLocaleKey = 'en_US';
            u_new.Office__c = 'test office' + i;
            u_new.Sales_Region__c = 'test sales region' + i;
            user_insert.add(u_new);
            i++;
        }
        Database.Saveresult[] lsr = Database.insert(user_insert);
        Set<ID> uIDs = new Set<ID>();
        for(Database.Saveresult sr : lsr){
            uIDs.add(sr.getID());
        }
        List<User> userList = [select ID, Name, Profile.Name from User where ID IN: uIDs];
        for(User u : userList){
            users.put(u.Profile.Name, u);
        }   
    }   
    
    static testMethod void testUserChange() {
        addUsers();
        User u = users.get(Advanced_Ad_Solutions);
        u.Pre_Sale_Manager__c = users.get(AAS_Operations_Team).Id;
        u.Post_Sale_Manager__c = users.get(Advanced_Ad_Solutions_AAS_Visitor).Id;
        u.Sales_Region__c = 'Sale Region 1';
        u.Office__c = 'Office 1';
        
        User delegated_Admin = users.get(Advanced_Ad_Solutions_Delegated_Admin);
        System.runAs(delegated_Admin){
            update u;
        }
    }
    
    static testMethod void testAccountOwnerWithOpportunity() {
        addUsers();
        User aas_user = users.get(Advanced_Ad_Solutions);
        User delegated_Admin = users.get(Advanced_Ad_Solutions_Delegated_Admin);
        
        Account a = new Account();
        a.RecordTypeId = RecordTypeHelper.GetRecordTypeIDByDevName('Account',  'Advanced_Ad_Solutions');
        a.Name = 'AAS account Test';
        Database.Saveresult a_sr;
        System.runAs(delegated_Admin){
            a_sr = Database.insert(a);
        }
        
        Opportunity o = new Opportunity();
        o.RecordTypeId = RecordTypeHelper.GetRecordTypeId('Opportunity', 'Advanced Ad Solutions');
        o.AccountId = a_sr.getId();
        o.Name = 'AAS opp test';
        o.StageName = 'dummy stage';
        o.CloseDate = Date.today().addDays(1);
        Database.Saveresult o_sr;
        initFirstFlags();
        System.runAs(delegated_Admin){
            o_sr = Database.insert(o);
        }
        
        Account a_rst = [select Id, OwnerId from Account where Id =: a_sr.getId() limit 1];
        a_rst.OwnerId = aas_user.Id;
        Database.Saveresult a_update_sr;
        initFirstFlags();
        //System.runAs(delegated_Admin){
            //a_update_sr = Database.update(a_rst);
        //}
        //Account a_rst_update = [select Id, OwnerId, Office__c, Sales_Region__c from Account where Id =: a_update_sr.getId() limit 1];
        
        //Opportunity o_rst = [select Id, OwnerId, Office__c, Sales_Region__c from Opportunity where Id =: o_sr.getId() limit 1];
        //System.assertEquals(a_rst_update.Office__c, o_rst.Office__c);
        //System.assertEquals(a_rst_update.Sales_Region__c, o_rst.Sales_Region__c);
    }
    
    static testmethod void testConvertLead(){
        addUsers();
        Lead myLead = new Lead(lastname = 'AAS', company='New AAS Lead');
        myLead.RecordTypeId = RecordTypeHelper.GetRecordTypeId('Lead', 'Advanced Ad Solutions');
        User aas_user = users.get(Advanced_Ad_Solutions);
        User delegated_Admin = users.get(Advanced_Ad_Solutions_Delegated_Admin);    
        System.runAs(delegated_Admin){  
            insert myLead;
        }
        Database.LeadConvert lc = new database.LeadConvert();
        lc.setLeadId(myLead.id);
        LeadStatus convertStatus = [Select Id, MasterLabel from LeadStatus where IsConverted=true limit 1];
        lc.setConvertedStatus(convertStatus.MasterLabel);
        Database.LeadConvertResult lcr;
        System.runAs(delegated_Admin){  
            lcr = Database.convertLead(lc);
        }
        System.assert(lcr.isSuccess());
    }
        
    static testmethod void testAASScheduler(){
        Test.startTest();
        AASUserBatchUpdateDaily a0 = new AASUserBatchUpdateDaily();
        String sch0 = AASUserBatchUpdateDaily.CRON_EXP_AAS;
        ID jobId = System.schedule('Test Schedule Batch upate Job0', sch0, a0);
        Test.stopTest();
        CronTrigger ct = [SELECT id, CronExpression, TimesTriggered, NextFireTime FROM CronTrigger WHERE id = :jobId];
        System.assertEquals(AASUserBatchUpdateDaily.CRON_EXP_AAS, ct.CronExpression); 
        System.assertEquals(0, ct.TimesTriggered);
    }
    
    static testmethod void testAASBatchUpdate(){
        addUsers();
        Map<ID, User> userwithId = new Map<ID, User>();
        for(User u : users.values()){
            userwithId.put(u.Id, u);
        }
        String qStr, oName;
        Datetime oneDaysAgo = Datetime.now().addDays(-1);
        oName = 'Account';
        AASUserBatchUpdateDaily accBatch = new AASUserBatchUpdateDaily(oName, userwithId);
        Id accBatch_id = database.executebatch(accBatch);
        AsyncApexJob ajob1 = [SELECT Id, Status, JobItemsProcessed, TotalJobItems, NumberOfErrors FROM AsyncApexJob WHERE ID =: accBatch_id ];
        System.AssertEquals(0, ajob1.NumberOfErrors);
                
        oName = 'Opportunity';
        AASUserBatchUpdateDaily oppBatch = new AASUserBatchUpdateDaily(oName, userwithId);
        Id oppBatch_id = database.executebatch(oppBatch);
        AsyncApexJob ajob2 = [SELECT Id, Status, JobItemsProcessed, TotalJobItems, NumberOfErrors FROM AsyncApexJob WHERE ID =: oppBatch_id ];
        System.AssertEquals(0, ajob2.NumberOfErrors);   
                
        oName = 'Lead';
        AASUserBatchUpdateDaily leadBatch = new AASUserBatchUpdateDaily(oName, userwithId);
        Id leadBatch_id = database.executebatch(leadBatch);
        AsyncApexJob ajob3 = [SELECT Id, Status, JobItemsProcessed, TotalJobItems, NumberOfErrors FROM AsyncApexJob WHERE ID =: leadBatch_id ];
        System.AssertEquals(0, ajob3.NumberOfErrors);       
    }   
    
    @future
    public static void testAASQuoteStatusUpdate()
    {
        addUsers();
        User aas_user = users.get(Advanced_Ad_Solutions);
        
        Account a = new Account();
        a.Post_Sale_Manager__c = aas_user.Id;
        a.RecordTypeId = RecordTypeHelper.GetRecordTypeIDByDevName('Account',  'Advanced_Ad_Solutions');
        a.Name = 'AAS account Test';
        insert a;
        
        Opportunity o = new Opportunity();
        o.RecordTypeId = RecordTypeHelper.GetRecordTypeId('Opportunity', 'Advanced Ad Solutions');
        o.AccountId = a.Id;
        o.Name = 'AAS opp test';
        o.StageName = 'Ascertainment by AE';
        o.Probability = 10;
        o.CloseDate = Date.today().addDays(1);  
        insert o; // default 10% probability
        
        Quote q = new Quote();
        q.Post_Sale_Manager__c = aas_user.Id;
        q.OpportunityId = o.Id;
        q.Name = 'Test Quote';
        q.Status = 'Quote Draft';
        insert q;
        
        /* change to Quote Requested */
        q.Status = 'Quote Requested';
        q.Due_Date__c = Date.today().addDays(1);
        update q;
        
        /* reset flag for creating duplicated tasks */
        if(AASFieldUpdateHelperClass.IsAASQuoteTaskCreated)
           AASFieldUpdateHelperClass.IsAASQuoteTaskCreated = false;
        
        /* chagen to Quote Returened */
        q.Status = 'Quote Returned';
        update q;
        
        /* check result, re-query */
        List<Quote> tQ = [SELECT Id, (SELECT Id, Subject FROM Tasks), Opportunity.Probability FROM Quote WHERE Id = :q.Id];
        system.assert(!tQ.isEmpty(), 'Test Quote is not found');
        system.assert(tQ[0].Opportunity.Probability == 35);
        system.assert(tQ[0].Tasks.size() == 2);
    }
}